package com.dmz.etc.server.task;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.extra.ftp.Ftp;
import com.dmz.etc.server.config.EnvConfig;
import com.dmz.etc.server.config.enums.MsgType;
import com.dmz.etc.server.config.enums.TaskStatus;
import com.dmz.etc.server.domain.ClientTask;
import com.dmz.etc.server.netty.client.NettyClient;
import com.dmz.etc.server.service.ClientService;
import com.dmz.etc.server.utils.FileUtil;
import com.dmz.etc.server.utils.etc.DateTools;
import com.dmz.etc.server.utils.ftp.FtpClient;
import com.dmz.etc.server.utils.ftp.FtpFile;
import com.dmz.etc.server.utils.ftp.FtpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Objects;

/**
 * @author Laptop
 */
@Slf4j
@Component
public class TaskService {

    @Resource
    private ClientService clientService;

    public boolean task2051() {
        try {
            ClientTask task = initTasks("2051");
            log.info("加载任务数据{}", task.getMsgType());
            if (checkTasks(task)) {
               return executeDayTask(task);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    public boolean task4031() {

        try {
            ClientTask task = initTasks("4031");
            log.info("加载任务数据{}", task.getMsgType());
            if (checkTasks(task)) {
               return executeDayTask(task);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    public boolean task4051() {
        try {
            ClientTask task = initTasks("4051");
            log.info("加载任务数据{}", task.getMsgType());
            if (checkTasks(task)) {
               return executeDayTask(task);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    private ClientTask initTasks(String type) {

        //2051  充值对账文件发送通知报文

        String endStr = EnvConfig.getProperty("dmz.ftp.file.fileName.end");
        String remotePath = EnvConfig.getProperty("dmz.ftp.file.path.bank");
        String localPath = EnvConfig.getProperty("dmz.ftp.file.path.temp");
        ClientTask clientTask = new ClientTask();
        if ("2051".equals(type)) {
            localPath = EnvConfig.getProperty("dmz.ftp.file.path.temp.2051");
            String fileName2051 = EnvConfig.getProperty("dmz.ftp.file.fileName.cz2051").replace("{yesterday}", DateTools.getYesterday()).replace("{today}", DateTools.getDateStr());
            log.info("fileName2051:{}", fileName2051);
            FtpFile file2051 = new FtpFile(null, remotePath, localPath, fileName2051, endStr);
            log.info(file2051.toString());

            clientTask.setFtpFile(file2051);
            clientTask.setTaskStatus(TaskStatus.STATUS_CREATED);
            clientTask.setMsgType(MsgType.TYPE_2051);
        }

        if ("4031".equals(type)) {
            Ftp ftp = new FtpClient().bankFtp();
            String fileName4031 = EnvConfig.getProperty("dmz.ftp.file.fileName.bc4031").replace("{yesterday}", DateTools.getYesterday()).replace("{today}", DateTools.getDateStr());
            log.info("fileName4031:{}", fileName4031);
            FtpFile file4031 = new FtpFile(ftp, remotePath, localPath, fileName4031, endStr);
            log.info(file4031.toString());

            clientTask.setFtpFile(file4031);
            clientTask.setTaskStatus(TaskStatus.STATUS_CREATED);
            clientTask.setMsgType(MsgType.TYPE_4031);
        }

        if ("4051".equals(type)) {
            Ftp ftp = new FtpClient().bankFtp();
            endStr = EnvConfig.getProperty("dmz.ftp.file.fileName.kj4051.end");
            String fileName4051 = EnvConfig.getProperty("dmz.ftp.file.fileName.kj4051").replace("{yesterday}", DateTools.getYesterday()).replace("{today}", DateTools.getDateStr());
            log.info("fileName4051:{}", fileName4051);
            FtpFile file4051 = new FtpFile(ftp, remotePath, localPath, fileName4051, endStr);
            log.info(file4051.toString());

            clientTask.setFtpFile(file4051);
            clientTask.setTaskStatus(TaskStatus.STATUS_CREATED);
            clientTask.setMsgType(MsgType.TYPE_4051);

        }
        return clientTask;
    }

    private boolean checkTasks(ClientTask task) {
        return !(task.getTaskStatus() == TaskStatus.STATUS_COMPLETE);
    }

    private boolean executeDayTask(ClientTask t) throws IOException {
        log.info("任务状态{}:{}", t.getMsgType().name(), t.getTaskStatus().name());
        switch (t.getTaskStatus()) {
            case STATUS_CREATED:
                if(Objects.equals(t.getMsgType().getType(), MsgType.TYPE_2051.getType())) {
                    log.info("判断文件在本地是否存在");
                    log.info(t.getFtpFile().toString());
                    if(FileUtil.localExist(t.getFtpFile())) {
                        t.setTaskStatus(TaskStatus.STATUS_FILE_DOWNLOADED);
                        log.info("判断本地文件存在，调用客户端发送报文1{}:{}", t.getMsgType(), t.getTaskStatus().name());
                        return asyncExecuteTask(t);
                    }else {
                        log.info("文件在本地不存在{}", t.getMsgType().name());
                    }
                }else {
                    log.info(t.getFtpFile().toString());
                    log.info("下载文件");
                    if (downloadFile(t.getFtpFile())) {
                        t.setTaskStatus(TaskStatus.STATUS_FILE_DOWNLOADED);
                        log.info("调用客户端发送报文2{}:{}", t.getMsgType(), t.getTaskStatus().name());
                        return asyncExecuteTask(t);
                    }else {
                        log.info("下载失败");
                    }
                }
                break;
            case STATUS_FILE_DOWNLOADED:
                log.info("调用客户端发送报文3{}:{}", t.getMsgType(), t.getTaskStatus().name());
                return asyncExecuteTask(t);
            default:
                return false;
        }
        return false;
    }

    private boolean asyncExecuteTask(ClientTask t) {
        //上传文件
        log.info("上传文件");
        boolean b = clientService.uploadFile(t.getFtpFile());
        if(b) {
            // 启动客户端发送报文
            try {
                if (FileUtil.localExist(t.getFtpFile())) {
                    t.setTaskStatus(TaskStatus.STATUS_SENDING);
                    //clientService.uploadFile(t.getFtpFile());
                    log.info("启动客户端==========================");
                    new NettyClient().start(t);
                    return true;
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }else {
            log.info("上传文件失败");
        }
        return false;
    }

    private boolean downloadFile(FtpFile file) throws IOException {
        try {
            if (FileUtil.localExist(file)) {
                log.info("本地有文件, 不需要下载");
                return true;
            }else {
                log.info("本地无文件,调用下载文件{}{}",file.getRemotePath(), file.getFileName());
                return FtpUtil.download(file);
            }
        } catch (IORuntimeException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new IOException(e);
        }
        return false;
    }
}